package utils

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"crypto/sha256"
	"encoding/base64"
	"io"

	"github.com/pkg/errors"
	"golang.org/x/crypto/pbkdf2"

	"changeme/internal/database"
)

// AESPasswordManager AES密码管理器
type AESPasswordManager struct {
	key []byte
}

// NewAESPasswordManager 创建AES密码管理器
func NewAESPasswordManager(masterPassword string) *AESPasswordManager {
	// 使用PBKDF2生成密钥
	salt := []byte("wails-database-manager-salt") // 在生产环境中应该使用随机盐
	key := pbkdf2.Key([]byte(masterPassword), salt, 10000, 32, sha256.New)

	return &AESPasswordManager{
		key: key,
	}
}

// Encrypt 加密密码
func (pm *AESPasswordManager) Encrypt(password string) (string, error) {
	if password == "" {
		return "", nil
	}

	block, err := aes.NewCipher(pm.key)
	if err != nil {
		return "", errors.Wrap(err, "failed to create cipher")
	}

	// 创建GCM模式
	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return "", errors.Wrap(err, "failed to create GCM")
	}

	// 生成随机nonce
	nonce := make([]byte, gcm.NonceSize())
	if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
		return "", errors.Wrap(err, "failed to generate nonce")
	}

	// 加密
	ciphertext := gcm.Seal(nonce, nonce, []byte(password), nil)

	// 编码为base64
	return base64.StdEncoding.EncodeToString(ciphertext), nil
}

// Decrypt 解密密码
func (pm *AESPasswordManager) Decrypt(encryptedPassword string) (string, error) {
	if encryptedPassword == "" {
		return "", nil
	}

	// 解码base64
	ciphertext, err := base64.StdEncoding.DecodeString(encryptedPassword)
	if err != nil {
		return "", errors.Wrap(err, "failed to decode base64")
	}

	block, err := aes.NewCipher(pm.key)
	if err != nil {
		return "", errors.Wrap(err, "failed to create cipher")
	}

	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return "", errors.Wrap(err, "failed to create GCM")
	}

	nonceSize := gcm.NonceSize()
	if len(ciphertext) < nonceSize {
		return "", database.ErrPasswordDecryption
	}

	nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
	plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
	if err != nil {
		return "", errors.Wrap(err, "failed to decrypt password")
	}

	return string(plaintext), nil
}

// SimplePasswordManager 简单密码管理器（用于开发/测试）
type SimplePasswordManager struct{}

// NewSimplePasswordManager 创建简单密码管理器
func NewSimplePasswordManager() *SimplePasswordManager {
	return &SimplePasswordManager{}
}

// Encrypt 简单加密（仅用于开发/测试）
func (pm *SimplePasswordManager) Encrypt(password string) (string, error) {
	if password == "" {
		return "", nil
	}
	// 简单的base64编码（不安全，仅用于开发）
	return base64.StdEncoding.EncodeToString([]byte(password)), nil
}

// Decrypt 简单解密（仅用于开发/测试）
func (pm *SimplePasswordManager) Decrypt(encryptedPassword string) (string, error) {
	if encryptedPassword == "" {
		return "", nil
	}
	// 简单的base64解码
	decoded, err := base64.StdEncoding.DecodeString(encryptedPassword)
	if err != nil {
		return "", errors.Wrap(err, "failed to decode password")
	}
	return string(decoded), nil
}
